/**
 * 
 */
package co.recloud.ariadne.thread;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

import co.recloud.ariadne.grammar.CommandParser;
import co.recloud.ariadne.grammar.ParseException;
import co.recloud.ariadne.model.logical.Command;
import co.recloud.ariadne.server.APIServer;

/**
 * @author alex
 * 
 */
public class APIThread extends Thread {

	private APIServer server;
	private Socket clientSocket;
	private ServerSocket serverSocket;
	private CommandParser parser;
	private boolean workMode;

	public APIThread(ServerSocket serverSocket) {
		this.serverSocket = serverSocket;
		workMode = false;
	}

	public APIThread(Socket clientSocket) {
		workMode = true;
		this.clientSocket = clientSocket;
		this.server = new APIServer();
		try {
			this.parser = new CommandParser(clientSocket.getInputStream());
		} catch (IOException e) {
		}
	}

	public void run() {
		if (workMode) {
			try {
				PrintWriter clientOut = new PrintWriter(
						clientSocket.getOutputStream());
				while (true) {
					try {
						Command command = parser.parse();
						int status = server.serve(clientSocket
								.getLocalAddress().toString().substring(1),
								clientSocket.getLocalPort(), command);
						if (status == 0) {
							clientOut.println("{status:'" + status + "'}");
						} else if (status == 1) {
							clientOut.println(server.getResultSet());
						}
						clientOut.flush();
						if (command.getCommandType() == Command.QUIT) {
							this.clientSocket.close();
							break;
						}
					} catch (ParseException e) {
						clientOut.println("{error:'" + e.getMessage() + "'}");
						clientOut.flush();
						parser.ReInit(clientSocket.getInputStream());
					}

				}
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		} else {
			while (true) {
				Socket clientSocket;
				if (serverSocket.isClosed()) {
					try {
						serverSocket.bind(serverSocket.getLocalSocketAddress());
					} catch (Exception e) {
						break;
					}
				}
				try {
					clientSocket = serverSocket.accept();
					Runnable clientThread = new APIThread(clientSocket);
					ThreadPool.startThread(clientThread);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}
